home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / b / b.lha / B / src / bint / b3sig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-24  |  4.1 KB  |  175 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2.  
  3. /*
  4.   $Header: b3sig.c,v 1.4 85/08/27 10:56:21 timo Exp $
  5. */
  6.  
  7. /*Handle interrupts and signals*/
  8.  
  9. #include "b.h"
  10. #include "b0fea.h"
  11. #include "b1obj.h"
  12. #include "b0con.h"
  13. #include "b3scr.h"
  14. #include "b3err.h"
  15. #include "b3env.h"
  16. #ifdef SETJMP
  17. #include <setjmp.h>
  18. #endif
  19.  
  20. #ifdef SIGNAL
  21. #include <signal.h>
  22. #endif
  23.  
  24. /*The operating system provides a function signal(s,f)
  25.   that associates function f with the signal s, and returns
  26.   a pointer to the previous function associated with s.
  27.   Then, when signal s occurs, f is called and the function associated with s
  28.   may or may not be reset. Thus f may need to call signal(s,f) again to.
  29.   The code here doesn't depend on either interpretation, always being explicit
  30.   about which handler to use.
  31.  
  32.   There are two signals that can come from the user: quit and interrupt.
  33.   Interrupt should just stop the interpreter and return to B command level;
  34.   quit should stop the B system completely.
  35.   All other signals are caused by errors (eg memory exhausted)
  36.   or come from outside the program, and are therefore fatal.
  37.  
  38.   SIG_IGN is the system supplied routine to ignore a signal.
  39.   SIG_DFL is the system supplied default for a signal.
  40.   kill(getpid(), signal) kills the program according to 'signal'
  41.  
  42.   On BSD systems, SIGTSTP and other signals causing the process to be
  43.   suspended, and SIGCONT and others that are ignored by default,
  44.   must not be caught.  It is assumed that all these are defined
  45.   when SIGTSTP is defined.
  46. */
  47.  
  48. #ifdef SIGTSTP
  49. Hidden bool must_handle(sig) int sig; {
  50.     /* Shouldn't we enumerate the list of signals we *do* want to catch? */
  51.     /* It seems that new signals are all of the type that should be
  52.        ignored by most processes... */
  53.     switch (sig) {
  54.     case SIGURG:
  55.     case SIGSTOP:
  56.     case SIGTSTP:
  57.     case SIGCONT:
  58.     case SIGCHLD:
  59.     case SIGTTIN:
  60.     case SIGTTOU:
  61.     case SIGIO:
  62.         return No;
  63.     default:
  64.         return Yes;
  65.     }
  66. }
  67. #else
  68. #ifdef SIGCLD /* System V */
  69. #define must_handle(sig) ((sig) != SIGCLD)
  70. #else
  71. #define must_handle(sig) Yes
  72. #endif
  73. #endif
  74.  
  75. #ifdef NOT_USED
  76. Visible Procedure dump() {
  77.     if (cntxt != In_prmnv) putprmnv();
  78. #ifdef KILL
  79.     signal(SIGQUIT, SIG_DFL);
  80.     kill(getpid(), SIGQUIT);
  81. #else
  82.     exit(-1);
  83. #endif
  84. }
  85. #endif NOT_USED
  86.  
  87. #ifdef SIGNAL
  88. Hidden Procedure oops(sig, m) int sig; string m; {
  89.     signal(sig, SIG_DFL); /* Don't call handler recursive -- just die... */
  90. #ifdef sigmask /* 4.2 BSD */
  91.     sigsetmask(0); /* Don't block signals in handler -- just die... */
  92. #endif
  93. #ifdef EXT_COMMAND
  94.     e_done();
  95. #endif
  96.     fflush(stdout);
  97.     fprintf(stdout, "*** Oops, %s\n", m);
  98.     fflush(stdout);
  99.     if (cntxt != In_prmnv) putprmnv();
  100. #ifdef KILL
  101.     kill(getpid(), sig);
  102. #else
  103.     exit(-1);
  104. #endif
  105. }
  106.  
  107. Hidden Procedure burp(sig) int sig; {
  108.     oops(sig,
  109.  "I feel suddenly (BURP!) indisposed. I'll call it a day. Sorry.");
  110. }
  111.  
  112. Hidden Procedure aog(sig) int sig; {
  113.     oops(sig,
  114.  "an act of God has occurred compelling me to discontinue service.");
  115. }
  116.  
  117. Hidden Procedure fpe_signal(sig) int sig; {
  118.     signal(sig /* == SIGFPE*/, fpe_signal);
  119.     syserr(MESS(3900, "unexpected arithmetic overflow"));
  120. }
  121.  
  122. #ifdef SETJMP
  123. extern bool awaiting_input;
  124. extern jmp_buf read_interrupt;
  125. #endif
  126.  
  127. Hidden Procedure intsig(sig) int sig; { /*sig==SIGINT*/
  128.     signal(sig, SIG_IGN);
  129.     int_signal();
  130.     signal(sig, intsig);
  131. #ifdef SETJMP
  132.     if (awaiting_input) longjmp(read_interrupt, 1);
  133. #endif
  134. }
  135.  
  136. #ifdef INTEGRATION
  137.  
  138. Visible Procedure bint_interrupt() {
  139.     signal(SIGINT, intsig);
  140.     if (interrupted) intsig(SIGINT);
  141. }
  142.  
  143. #endif
  144.  
  145. Hidden int(* setsig(sig, func))() int sig, (*func)(); {
  146.     /*Set a signal, unless it's being ignored*/
  147.     int (*f)()= signal(sig, SIG_IGN);
  148.     if (f != SIG_IGN) signal(sig, func);
  149.     return f;
  150. }
  151. #endif
  152.  
  153. Visible Procedure initsig() {
  154. #ifdef SIGNAL
  155.     int i;
  156.     for (i = 1; i<=NSIG; ++i)
  157.         if (must_handle(i)) VOID setsig(i, burp);
  158. #ifndef INTEGRATION
  159.     if (filtered) {
  160.         VOID setsig(SIGINT,  SIG_IGN);
  161.         VOID setsig(SIGTRAP, intsig);
  162.     } else {
  163.         VOID setsig(SIGINT,  intsig);
  164.         VOID setsig(SIGTRAP, burp);
  165.     }
  166. #else
  167.     VOID setsig(SIGINT,  intsig);
  168. #endif
  169.     VOID setsig(SIGQUIT, aog);
  170.     VOID setsig(SIGTERM, aog);
  171.     VOID setsig(SIGFPE,  fpe_signal);
  172.     VOID setsig(SIGPIPE, bye);
  173. #endif SIGNAL
  174. }
  175.